﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PacketAnalyzer.Data;

namespace PacketAnalyzer.Analyzer
{
    public class ZentecHeaderAnalyzer
    {
        private static ZentecHeaderAnalyzer instance = null;
        private static object syncRoot = new object();

        public static ZentecHeaderAnalyzer GetInstance()
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new ZentecHeaderAnalyzer();
                }
            }

            return instance;
        }

        public ZentecHeaderAnalyzer()
        {
        }

        public PacketData Analyze(string packet)
        {
            int pos = 0;

            PacketData fepHeader = AnalyzeFepHeader(packet);
            pos += fepHeader.Length;

            string fepHeaderType = fepHeader.Get("전문코드");

            if (!fepHeaderType.Equals("DATA") )
                return fepHeader;

            PacketData pbHeader = AnalyzePowerBaseHeader(packet.Substring(pos));
            pos += pbHeader.Length;

            PacketData pbUHeader = AnalyzePowerBaseUserHeader(packet.Substring(pos));

            // Header 다 합쳐서 Return.
            fepHeader = fepHeader.Merge(pbHeader);
            fepHeader = fepHeader.Merge(pbUHeader);

            return fepHeader;
        }

        private PacketData AnalyzeFepHeader(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            pos = packetData.AddResult(packet, "Start 구분자", 1, pos, null);
            pos = packetData.AddResult(packet, "Data 길이", 5, pos, null);
            pos = packetData.AddResult(packet, "업무구분자", 6, pos, null);
            pos = packetData.AddResult(packet, "업무계 장비 구분", 4, pos, null);
            pos = packetData.AddResult(packet, "전문코드", 4, pos, null);
            pos = packetData.AddResult(packet, "응답코드", 2, pos, ZentecDescription.ErrorCode);
            pos = packetData.AddResult(packet, "일자", 8, pos, null);
            pos = packetData.AddResult(packet, "시간", 9, pos, null);
            pos = packetData.AddResult(packet, "일련번호", 8, pos, null);
            pos = packetData.AddResult(packet, "Filler", 14, pos, null);

            return packetData;
        }

        private PacketData AnalyzePowerBaseHeader(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            pos = packetData.AddResult(packet, "전문길이", 6, pos, null);
            pos = packetData.AddResult(packet, "전문구분", 1, pos, null);
            pos = packetData.AddResult(packet, "압축구분", 1, pos, null);
            pos = packetData.AddResult(packet, "암호화구분", 1, pos, null);
            pos = packetData.AddResult(packet, "데이터 옵셋", 3, pos, null);
            pos = packetData.AddResult(packet, "서비스코드", 8, pos, null);
            pos = packetData.AddResult(packet, "이용사번호", 3, pos, null);
            pos = packetData.AddResult(packet, "사용자ID", 16, pos, null);
            pos = packetData.AddResult(packet, "접속분류코드", 2, pos, null);
            pos = packetData.AddResult(packet, "접속채널번호", 3, pos, null);
            pos = packetData.AddResult(packet, "트랜잭션순차번호", 9, pos, null);
            pos = packetData.AddResult(packet, "트랜잭션추적ID", 16, pos, null);
            pos = packetData.AddResult(packet, "공인IP", 12, pos, null);
            pos = packetData.AddResult(packet, "사설IP", 12, pos, null);
            pos = packetData.AddResult(packet, "처리지점 번호", 3, pos, null);
            pos = packetData.AddResult(packet, "지점번호", 3, pos, null);
            pos = packetData.AddResult(packet, "단말분류코드", 5, pos, null);
            pos = packetData.AddResult(packet, "단말번호", 3, pos, null);
            pos = packetData.AddResult(packet, "언어구분", 1, pos, null);
            pos = packetData.AddResult(packet, "AP처리시각", 9, pos, null);
            pos = packetData.AddResult(packet, "메시지코드", 4, pos, null);
            pos = packetData.AddResult(packet, "출력메시지구분", 1, pos, null);
            pos = packetData.AddResult(packet, "압축요청구분", 1, pos, null);
            pos = packetData.AddResult(packet, "기능키목록", 4, pos, null);
            pos = packetData.AddResult(packet, "요청 레코드 개수", 4, pos, null);
            pos = packetData.AddResult(packet, "예외처리", 2, pos, null);
            pos = packetData.AddResult(packet, "예비영역", 4, pos, null);
            pos = packetData.AddResult(packet, "연속여부", 1, pos, null);
            pos = packetData.AddResult(packet, "연속키", 18, pos, null);
            pos = packetData.AddResult(packet, "가변시스템정보길이", 2, pos, null);
            pos = packetData.AddResult(packet, "가변헤더정보길이", 2, pos, null);
            pos = packetData.AddResult(packet, "가변메시지길이", 2, pos, null);

            int messageLength = int.Parse(packetData.Get("가변메시지길이"));

            pos = packetData.AddResult(packet, "가변메시지", messageLength, pos, null);

            return packetData;
        }

        private PacketData AnalyzePowerBaseUserHeader(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            pos = packetData.AddResult(packet, "Memory Index", 3, pos, null);
            pos = packetData.AddResult(packet, "Process name", 11, pos, null);
            pos = packetData.AddResult(packet, "시장구분", 2, pos, null);
            pos = packetData.AddResult(packet, "계좌번호 뒤 2자리", 2, pos, null);
            pos = packetData.AddResult(packet, "예비", 32, pos, null);

            return packetData;
        }
    }
}
